package vip.zhenzicheng.concurrent_program.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @author zhenzicheng
 * @DESCRIPTION: 线程创建的四中方式
 * @DATE: 2022/05/09 4:42 PM
 */
public class CreateThreadDemo {
  public static final String NEW_LINE = "********** **********";

  /**
   * 1. 继承Thread <br/>
   * 2. 实现Runnable接口 <br/>
   * 3. 实现Callable接口 + FutureTask <br/>
   * 4. 线程池 将任务提交给线程池来执行
   * <pre>区别:
   * 1-> 1-2 无返回值 3可获取返回值
   * 2-> 1-2-3都不能控制资源
   * 3-> 只有4(线程池)可以控制资源，性能稳定
   * </pre>
   */
  public static void main(String[] args) {
    // 1. 继承Thread
    wayOne();

    // 2. 实现Runnable接口
    wayTwo();
    // 2. 实现Runnable接口 + lambda
    wayTwoNew();

    // 3. 实现Callable接口 + FutureTask
    wayThree();

    /*
     * 因为线程的创建是非常浪费资源，所以在程序设计时推荐使用线程池，而不是使用原生前三种方式！
     */
    wayFour();
  }

  public static void wayOne() {
    Thread01 thread = new Thread01();
    thread.start();
  }

  public static void wayTwo() {
    // 匿名内部类方式
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        System.out.println("我是第二种方式...");
        System.out.println(NEW_LINE);
      }
    };
    Thread thread = new Thread(runnable, "t1");
    thread.start();

    // 实现接口方式
    new Thread(new Runnable01(), "t1")
        .start();
  }

  public static void wayTwoNew() {
    new Thread(() -> System.out.println("我是第二种的新版写法~，使用了lambda表达式简化匿名内部类~\n" + NEW_LINE), "xxx01")
        .start();
  }

  public static void wayThree() {
    // lambda函数式接口方式
    Callable<Integer> callable = () -> {
      int i = 1000;
      while (i > 10) {
        i /= 2.5;
      }
      System.out.println("我是第三种方式，计算结果为:[" + i + "]");
      System.out.println(NEW_LINE);
      return i;
    };

    FutureTask<Integer> futureTask = new FutureTask<>(callable);
    new Thread(futureTask, "t3")
        .start();

    try {
      /*
       * 使用futureTask的最大好处就是可以使用阻塞等待获取结果 在此时即为同步
       */
      Integer result = futureTask.get();

    } catch (InterruptedException | ExecutionException e) {
      e.printStackTrace();
    }
    // System.out.println();
  }

  /**
   * 线程池demo请参照: {@link ThreadPoolDemo 线程池demo}
   */
  public static void wayFour() {

  }

  private static class Thread01 extends Thread {
    @Override
    public void run() {
      System.out.println("我是第一种(最原生)方式，我的线程id:[" + Thread.currentThread().getId() + "]");
      System.out.println(NEW_LINE);
    }
  }

  private static class Runnable01 implements Runnable {
    @Override
    public void run() {
      System.out.println("实现了runnable接口的方式");
    }
  }

}
